interface Transform {
    rotateX: number;
    rotateY: number;
    translateZ: number;
}
class MouseTransform {
    private transform: Transform;
    // 鼠标最后位置
    private lastX = 0;
    private lastY = 0;
    // 鼠标移动距离
    private reduceX = 0;
    private reduceY = 0;
    // 鼠标移动时间戳
    private moveTime = 0;
    // 衰减定时器
    private decayTimer = 0;
    // 是否按下鼠标
    private isDown = false;

    public constructor(transform: Transform) {
        this.transform = transform;
    }
    // 鼠标按下处理
    public mousedown(event: MouseEvent): void {
        this.isDown = true;
        this.lastX = event.clientX;
        this.lastY = event.clientY;
        this.reduceX = this.reduceY = 0;
        this.moveTime = 0;
        //取消掉还没完成的惯性
        cancelAnimationFrame(this.decayTimer);
    }
    // 鼠标移动处理
    public mousemove(event: MouseEvent): void {
        if (!this.isDown) return;
        this.reduceX = event.clientX - this.lastX;
        this.reduceY = event.clientY - this.lastY;

        this.transform.rotateX -= this.reduceY * 0.15;
        this.transform.rotateY += this.reduceX * 0.15;

        this.lastX = event.clientX;
        this.lastY = event.clientY;

        this.moveTime = Date.now();
    }
    // 鼠标释放处理
    public mouseup(): void {
        this.isDown = false;
        if (Date.now() - this.moveTime < 100) {
            this.decayTimer = requestAnimationFrame(this.decay.bind(this));
        }
    }
    // 鼠标滚动处理
    public mousewheel(event: WheelEvent): void {
        this.transform.translateZ -= event.deltaY;
    }
    // 鼠标离开处理
    public mouseleave(): void {
        this.isDown = false;
    }
    // 衰退递归
    public decay(): void {
        this.reduceX *= 0.9;
        this.reduceY *= 0.9;
        this.transform.rotateX -= this.reduceY * 0.15;
        this.transform.rotateY += this.reduceX * 0.15;

        if (Math.abs(this.reduceX) < 0.1 && Math.abs(this.reduceY) < 0.1) {
            return;
        }
        this.decayTimer = requestAnimationFrame(this.decay.bind(this));
    }
}
export default MouseTransform;
